﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Data.Xml.Dom;
using System.Runtime.Serialization.Json;
using Windows.Storage;
using System.IO;
using mBook.Models;
using mBook.Utils;
namespace mBook.ViewModels
{
    public class EpubViewModel
    {
        public static EpubEbook ParseToEbook(string rootFolder, string filename, XmlDocument doc)
        {
            EpubEbook ebook = new EpubEbook();
            ebook.Items = new Dictionary<string, string>();
            ebook.Spine = new List<string>();
            ebook.RootFolder = rootFolder;
            ebook.FileName = filename;

            var metadatas = doc.GetElementsByTagName("metadata");
            foreach (var metadata in metadatas)
            {
                var itemNodes = metadata.ChildNodes;
                foreach (var item in itemNodes)
                {
                    if (item.NodeType == NodeType.ElementNode)
                    {
                        switch (item.NodeName)
                        {
                            case "dc:title": ebook.Title = item.InnerText; break;
                            case "dc:language": ebook.Language = item.InnerText; break;
                            case "dc:identifier": ebook.Identifier = item.InnerText; break;
                            case "dc:creator": ebook.Creator = item.InnerText; break;
                            case "dc:publisher": ebook.Publisher = item.InnerText; break;
                            case "dc:description": ebook.Description = item.InnerText; break;
                            case "dc:coverage": ebook.Coverage = item.InnerText; break;
                            case "dc:source": ebook.Source = item.InnerText; break;
                            case "dc:rights": ebook.Rights = item.InnerText; break;
                            case "dc:date":
                                {
                                    string date = item.InnerText;
                                    ebook.Date.Add(date);
                                    break;
                                }
                            case "dc:subject":
                                {
                                    string subject = item.InnerText;
                                    ebook.Subject.Add(subject);
                                    break;
                                }
                            default: break;
                        }
                    }
                }
            }
            

            var manifests = doc.GetElementsByTagName("manifest");
            foreach (var manifest in manifests)
            {
                var itemNodes = manifest.ChildNodes;
                foreach (var item in itemNodes)
                {
                    if (item.NodeType == NodeType.ElementNode)
                    {
                        string id = item.Attributes.GetNamedItem("id").NodeValue as string;
                        string href = item.Attributes.GetNamedItem("href").NodeValue as string;

                        ebook.Items.Add(id, href);
                    }
                }
            }

            if (ebook.Items.ContainsKey("book-cover"))
                ebook.ImageCover = ebook.Items["book-cover"];

            XmlNodeList spines = doc.GetElementsByTagName("spine");
            foreach (var spine in spines)
            {
                var spineItems = spine.ChildNodes;
                foreach (var item in spineItems)
                {
                    if (item.NodeType == NodeType.ElementNode)
                    {
                        string idRef = item.Attributes.GetNamedItem("idref").NodeValue as string;

                        String isShow = item.Attributes.GetNamedItem("linear").NodeValue as string;
                        if (string.Compare(isShow,"yes",StringComparison.CurrentCultureIgnoreCase) == 0)
                        {
                            ebook.Spine.Add(idRef);
                        }
                        //else
                        //{
                        //    if (string.Compare(idRef, "cover", StringComparison.CurrentCultureIgnoreCase) == 0)
                        //    {
                        //        ebook.Spine.Add(idRef);
                        //    }
                        //}

  
                    }
                }
            }

            return ebook;
        }

        public static async void CreateJsonEbook(EpubEbook ebook)
        {
            DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(ebook.GetType());

            StorageFolder folderEbook = await ApplicationData.Current.LocalFolder.CreateFolderAsync(Constants.FOLDER_DATA_EXTRACT, CreationCollisionOption.OpenIfExists);
            StorageFile outputFile = await folderEbook.CreateFileAsync(ebook.FileName + "\\config", CreationCollisionOption.OpenIfExists);

            Stream stream = await outputFile.OpenStreamForWriteAsync();

            jsonSerializer.WriteObject(stream, ebook);
            
        }

        public static async Task CreateJsonEbook2(EpubEbook ebook)
        {
            DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(ebook.GetType());

            StorageFolder folderEbook = await ApplicationData.Current.LocalFolder.CreateFolderAsync(Constants.FOLDER_DATA_EXTRACT, CreationCollisionOption.OpenIfExists);
            StorageFile outputFile = await folderEbook.CreateFileAsync(ebook.FileName + "\\config", CreationCollisionOption.OpenIfExists);

            Stream stream = await outputFile.OpenStreamForWriteAsync();

            jsonSerializer.WriteObject(stream, ebook);

        }



        public static async Task<Object> ParseFileToEbook(StorageFile file)
        {
            DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(EpubEbook));
            Stream stream = await file.OpenStreamForReadAsync();

            var ebook = jsonSerializer.ReadObject(stream);

            return ebook;
        }

        public static async Task<List<ItemTableContent>> parseTableContent(XmlDocument doc)
        {
            List<ItemTableContent> listItems = new List<ItemTableContent>();

            var navs = doc.GetElementsByTagName("nav");
            foreach (var nav in navs)
            {
                String value = nav.Attributes.GetNamedItem("epub:type").NodeValue as String;
                if (value != null && value == "toc")
                {
                    var ols = nav.ChildNodes;
                    foreach (var ol in ols)
                    {
                        if (ol.NodeName == "ol")
                        {
                            var lis = ol.ChildNodes;
                            foreach (var li in lis)
                            {
                                if (li.NodeName == "li")
                                {
                                    ItemTableContent item = new ItemTableContent();
                                    await readItem(li as XmlElement, item);
                                    listItems.Add(item);
                                }
                            }
                        }
                    }
                }
                else
                    break;
            }

            return listItems;
        }

        private static async Task readItem(XmlElement element, ItemTableContent item)
        {


            var nodes = element.ChildNodes;
            foreach (var node in nodes)
            {
                if (node.NodeName == "a")
                {
                    if (node.ChildNodes.Count > 0)
                    {
                        var spans = node.ChildNodes;
                        foreach (var span in spans)
                        {
                            if (span.NodeName == "span" && (span.Attributes.GetNamedItem("class").NodeValue as String).Contains("label"))
                            {
                                string name = span.InnerText;
                                item.Name = name;
                                break;
                            }
                        }

                        if (item.Name == null || item.Name == "")
                        {
                            item.Name = node.InnerText;
                        }

                        string href = node.Attributes.GetNamedItem("href").NodeValue as string;
                        item.Href = href;
                    }
                    else
                    {
                        string name = node.InnerText;
                        string href = node.Attributes.GetNamedItem("href").NodeValue as string;
                        item.Name = name;
                        item.Href = href;
                    }
                }
                else
                {
                    if (node.NodeName == "ol")
                    {
                        List<ItemTableContent> listChildItems = new List<ItemTableContent>();
                        var lis = node.ChildNodes;
                        foreach (var li in lis)
                        {
                            if (li.NodeName == "li")
                            {
                                ItemTableContent childItem = new ItemTableContent();
                                await readItem(li as XmlElement, childItem);
                                listChildItems.Add(childItem);
                            }
                        }
                        item.ListChildItems = listChildItems;
                    }
                }
            }
        }
    }
}
